package com.childmiles.gwt.client.ui;

import java.util.List;

import com.childmiles.gwt.client.AwardWinnerService;
import com.childmiles.gwt.client.AwardWinnerServiceAsync;
import com.childmiles.gwt.client.domain.Award;
import com.childmiles.gwt.client.domain.AwardWinner;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Widget;

/**
 * Popup for editing an awards. Takes care of refreshing AwardPanel.
 *
 */
public class EditAwardsDialog extends DialogBox {

    private static final String AWARD_PANEL_EDITING_STYLE = "awardPanelEditing";

    private FlowPanel content;

    //We refresh this. Also handy that it knows the day number. 
    private final AwardPanel awardPanel;

    //The model
    private final AwardWinner awardWinner;

    private Integer awardsDayNumber;

    private final AwardWinnerServiceAsync awardWinnerService;

    public EditAwardsDialog(AwardWinnerServiceAsync awardWinnerService, AwardWinner awardWinner, final AwardPanel awardPanel) {
        this.awardWinnerService = awardWinnerService;
        this.awardWinner = awardWinner;
        this.awardPanel = awardPanel;
        this.awardsDayNumber = awardPanel.getDayNumber();
        this.setPopupPosition(15,180);
        this.addStyleName("editAwardsDialog");
        this.setGlassEnabled(true);
        this.setAnimationEnabled(true);

        awardPanel.addStyleName(AWARD_PANEL_EDITING_STYLE);
        setText("Edit Day " + awardsDayNumber);
        content = new FlowPanel();
        refreshContent();
        setWidget(content);
    }

    /**
     * Refresh awardPanel and ourself
     */
    private void refreshContent() {
        content.clear();
        final List<Award> awards = awardWinner.getAwardsForDay(awardsDayNumber);
        //Add Button

        final Button addButton = new Button("Add");
        addButton.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) { //add new Award
                Award newAward = new Award("new");
                awardWinner.getAwards().add(awardsDayNumber, newAward);
                saveAwardWinner();
                checkForPrizes(awards);
                refreshAwardsPanel();
                //update ourself
                int awardSequenceNumber = awards.size();
                content.insert(createAwardEditPanel(newAward), awardSequenceNumber);
                //Disallow more than 9 awards
                addButton.setEnabled(awards.size() < 9);
            }

            private void checkForPrizes(final List<Award> awards) {
                if (awards.size() % 3 == 0) {
                    //Window.alert(awards.size() + " Awards! You won a prize!");
                }
            }
        });
        content.add(addButton);

        //Awards with Delete buttons
        for (Award award : awards) {
            content.add(createAwardEditPanel(award));
        }

        //OK Button
        Button okButton = new Button("OK");
        okButton.addStyleName("okButton");
        okButton.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                hide();
            }
        });
        content.add(okButton);
    }

    private Widget createAwardEditPanel(final Award award) {
        final FlowPanel awardEditPanel = new FlowPanel();
        //awardEditPanel.add(new Label(award.getName()));
        final Image awardImage = new Image(award.getImageURL());
        awardImage.setTitle("Click to change image");
        awardImage.addStyleName("awardImageSmall");
        awardImage.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                award.changeToNextImage();
                awardImage.setUrl(award.getImageURL());
                //udpate award in awardWinner object and save
                awardWinner.getAwards().findByDate(award.getAdded()).setImageURL(award.getImageURL());
                saveAwardWinner();
                refreshAwardsPanel();
            }
        });
        awardEditPanel.add(awardImage);
        Image removeButton = new Image("/images/delete.gif");
        removeButton.setTitle("Remove award");
        removeButton.addStyleName("horizontal");
        removeButton.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                awardWinner.getAwards().remove(awardsDayNumber,award);
                saveAwardWinner();
                refreshAwardsPanel();
                refreshContent();
            }

        });
        awardEditPanel.add(removeButton);
        return awardEditPanel;
    }
    
    protected void saveAwardWinner() {
        awardWinnerService.save(awardWinner, new AsyncCallback() {
            public void onFailure(Throwable e) {
                throw new RuntimeException(e);
            }
            public void onSuccess(Object result) {
                //Good, do nothing
            }
        });
        
    }

    private void refreshAwardsPanel() {
        awardPanel.refreshContents(awardWinner.getAwardsForDay(awardsDayNumber));
    }
    
    /**
     * Un-gray awardPanel cell when hidden
     */
    @Override
    public void hide() {
        awardPanel.removeStyleName(AWARD_PANEL_EDITING_STYLE);
        super.hide();
    }

    /**
     * Close on enter and esc
     */
    public boolean onKeyPressPreview(char key, int modifiers) {
        switch (key) {
        case KeyCodes.KEY_ENTER:
        case KeyCodes.KEY_ESCAPE:
            hide();
            break;
        }
        return true;
    }

}
